﻿// YamlLanguagePreferences.cs
//
// Copyright 2008 by Burt Harris
// Licensed under the Microsoft Public License (Ms-PL)
// See: http://www.codeplex.com/yaml/license
//

using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Package;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;

namespace YaTools.Yaml.LanguagePackage
{
    /// <summary>
    /// This class exists to workaround several problems with the VS9 SDK's YamlLanguagePreferences class.
    /// </summary>
    internal class YamlLanguagePreferences : LanguagePreferences
    {
        // Parameterless constructor causes problems with parsing

        public YamlLanguagePreferences(IServiceProvider serviceProvider, Guid languageGuid, string languageName)
            : base(serviceProvider, languageGuid, languageName)
        {
        }

        public override void Init()
        {
            base.Init();

            //
            // Base class's initialize doesn't read the "run as normal user" (RANU) copy of 
            // the language preferences in the users's registry, for the non-administrator
            // development case.   We'll repeat it here using the new ILocalRegistry4 interface.
            //
            DoInit(VsLocalRegistryType.Configuration, InitMachinePreferences);
            DoInit(VsLocalRegistryType.UserSettings, InitUserPreferences);
        }

        private void DoInit(VsLocalRegistryType type, InitFunction function)
        {
            string key;
            uint hive;

            var registry = Site.GetService(
                typeof (SLocalRegistry)) as ILocalRegistry4;

            if (registry == null)
                throw new InvalidOperationException("Unable to locate registry service");

            int hr = registry.GetLocalRegistryRootEx((uint) type, out hive, out key);
            if (hr < 0) Marshal.ThrowExceptionForHR(hr);

            switch ((RegistryHive) hive)
            {
                case RegistryHive.CurrentUser:
                    function(Registry.CurrentUser, key);
                    break;
                case RegistryHive.CurrentConfig:
                    function(Registry.CurrentConfig, key);
                    break;
            }
        }

        #region Nested type: InitFunction

        private delegate void InitFunction(RegistryKey key, string name);

        #endregion

        #region Nested type: VsLocalRegistryType

        private enum VsLocalRegistryType
        {
            UserSettings = 1,
            Configuration = 2,
            PrivateConfig = 3,
            SessionSettings = 4,
            NewUserSettings = 5
        } ;

        #endregion
    }
}